package tree.operators;

import utils.Utils;

public abstract class Op implements IOp {
	
	private static final int ALL_OPS_TOTAL_WEIGHT = 12;

	protected int arity = 0;

	@Override
	public int arity() {
		return arity;
	}
	
	public static IOp createRandomOp()
	{
		double rand = Utils.rand.nextDouble() * ALL_OPS_TOTAL_WEIGHT;
		
		if (rand <= 1)
		{
			return new CosOp();
		}
		if (rand <= 2)
		{
			return new DivOp();
		}
		if (rand <= 3)
		{
			return new IdentityOp();
		}
		if (rand <= 4)
		{
			return new MinusOp();
		}
		if (rand <= 5)
		{
			return new MultOp();
		}
		if (rand <= 6)
		{
			return new PlusOp();
		}
		if (rand <= 7)
		{
			return new SinOp();
		}
		if (rand <= ALL_OPS_TOTAL_WEIGHT)
		{
			return new ConstOp(Utils.rand.nextGaussian() * 10 + 5);
		}
		
		return null;
	}
	
	/**
	 * Create random operation with arity 0.
	 * @return
	 */
	public static IOp createRandomTerminalOp()
	{
		double rand = Utils.rand.nextDouble();
		
		if (rand <= 0.75)
		{
			return new ConstOp(Utils.rand.nextGaussian());
		}
		else
		{
			return new IdentityOp();
		}
		
	}
	
	public abstract String toString();

}
